package TI;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import Exceptions.NoProductsSelectedException;
import Exceptions.ProductSalesPriceNeverSetException;
import Magnitudes.Money;
import Magnitudes.Pesos;
import Products.Presentation;
import junit.framework.TestCase;
import static org.mockito.Mockito.*;

public class ParticularCustomerTest extends TestCase {

	ParticularCustomer customerToTest;
	BranchOffice branchOffice = mock(BranchOffice.class);
	Presentation presentation = mock(Presentation.class);
	Address address = mock(Address.class);
	
	@Before
	public void setUp(){
		customerToTest = new ParticularCustomer("123", "Fideo", "fideo@afa.com.ar", address);
	}
	
	@Test
	public void testGivenTwoParticularCustomersWithTheSameCuitIDWhenAskIsEqualsShoutldReturnTrue(){
		ParticularCustomer customer = new ParticularCustomer("123", "DiMaria", "angelito@afa.com.ar", address);
		assertTrue(customerToTest.isEquals(customer));
	}
	
	@Test
	public void testGivenTwoParticularCustomersWithDifferentCuitIDWhenAskIsEqualsShoutldReturnFalse(){
		ParticularCustomer customer = new ParticularCustomer("321", "Pipita", "pipita@afa.com.ar", address);
		assertFalse(customerToTest.isEquals(customer));
	}
	
	@Test
	public void testGivenACustomerWhenDeliveryAddressIsNotSetGetAddressAndGetDeliveryAddressShouldReturnTheSame(){
		assertSame(customerToTest.getHomeAddress(), customerToTest.getDeliveryAddress());
	}
	
	@Test
	public void testGivenACustomerWhenDeliveryAddressIsSetAnotherAddressGetAddressAndGetDeliveryAddressShouldReturnIsNotTheSame(){
		Address anotherAddress = mock(Address.class);
		customerToTest.setDeliveryAddress(anotherAddress);
		assertNotSame(customerToTest.getHomeAddress(), customerToTest.getDeliveryAddress());
	}
	
	@Test
	public void testGivenAParticularCustomerWhenBuyShouldSendSelfAndAListOfProductsToTheBranchOffice(){
		List<Presentation> products = new ArrayList<Presentation>();
		products.add(presentation);
		try {
			customerToTest.buy(products, branchOffice);
		} catch (NoProductsSelectedException e1) {
			e1.printStackTrace();
		} catch (ProductSalesPriceNeverSetException e1) {
			e1.printStackTrace();
		}
		try {
			verify(branchOffice).registerQuickBuy(customerToTest, products);
		} catch (ProductSalesPriceNeverSetException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testGivenAParticularCustomerWhenBuyWithAnEmptyProductsShouldRaiseNoProductsSelectedException(){
		List<Presentation> products = new ArrayList<Presentation>();
		Exception exception = null;
		try {
			try {
				customerToTest.buy(products, branchOffice);
			} catch (ProductSalesPriceNeverSetException e) {
				e.printStackTrace();
			}
		} catch (NoProductsSelectedException noProductsSelectedException){
			exception = noProductsSelectedException;
		}
		
		assertNotNull(exception);
		assertTrue(exception.getMessage().contains("Products should have at least one presentation"));
	}
	
	@Test
	public void testGivenAParticularCustomerWithNoProductsReturnedGetCurrentAccountAmountShouldReturnZeroPesos(){
		assertTrue(customerToTest.getCurrentAccountAmount().amount() == 0);
	}
	
//	@Test
//	public void testGivenAParticularCustomerWithProductsReturnedGetCurrentAccountAmountShouldReturnMoreThanZeroPesos(){
//		customerToTest.returnProduct(presentation, branchOffice);
//		try {
//			when(presentation.getUnitSalesPrice()).thenReturn(new Pesos(10));
//		} catch (ProductSalesPriceNeverSetException e) {
//			e.printStackTrace();
//		}
//		assertFalse(0 == customerToTest.getCurrentAccountAmount().amount());
//	}
}
